// Copyright 2017 ETH Zurich and University of Bologna.
// -- Adaptable modifications made for hbirdv2 SoC. -- 
// Copyright 2020 Nuclei System Technology, Inc.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

module spi_master_clkgen (
    input  wire         clk,
    input  wire         rstn,
    input  wire         en,
    input  wire [7:0]   clk_div,
    input  wire         clk_div_valid,
    input  wire         spi_cpol_i,     // 时钟极性寄存器 (0: 空闲低电平, 1: 空闲高电平)
    input  wire         spi_cpha_i,     // 时钟相位寄存器 (0: 第一个边沿采样, 1: 第二个边沿采样)
    output reg          spi_cpol_o,
    output reg          spi_cpha_o,
    output reg          spi_clk,
    output reg          spi_fall,
    output reg          spi_rise
);

    reg [7:0] counter_trgt;
    reg [7:0] counter_trgt_next;
    reg [7:0] counter;
    reg [7:0] counter_next;

    reg       spi_clk_next;
    reg       running;

//  wire idle_level = spi_cpol_o ? 1'b1 : 1'b0;

    // 同步更新 spi_cpol/spi_cpha 配置
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            spi_cpol_o <= 1'b0;  // 默认 spi_cpol=0 (Mode 0)
            spi_cpha_o <= 1'b0;  // 默认 spi_cpha=0 (Mode 0)
        end else if ( !en ) begin
            spi_cpol_o <= spi_cpol_i;
            spi_cpha_o <= spi_cpha_i;
        end
    end

    always @(*) begin
        spi_rise = 1'b0;
        spi_fall = 1'b0;

        if (clk_div_valid)
            counter_trgt_next = clk_div;
        else
            counter_trgt_next = counter_trgt;

        if (counter == counter_trgt || clk_div_valid && (clk_div == counter)) begin
            counter_next = 0;
            spi_clk_next =clk_div_valid ? spi_clk :  ~spi_clk;
            
            // // 边沿检测逻辑（根据当前 spi_cpol/spi_cpha 动态判断）
            // case ({spi_cpol_o, spi_cpha_o})
            //     // Mode 0 (spi_cpol=0, spi_cpha=0)
            //     2'b00: begin
            //         if (spi_clk == 1'b1) spi_rise = running; // 下降沿（数据切换）
            //         if (spi_clk == 1'b0) spi_fall = running; // 上升沿（数据采样）
            //     end
            //     // Mode 1 (spi_cpol=0, spi_cpha=1)
            //     2'b01: begin
            //         if (spi_clk == 1'b0) spi_rise = running; // 上升沿（数据切换）
            //         if (spi_clk == 1'b1) spi_fall = running; // 下降沿（数据采样）
            //     end
            //     // Mode 2 (spi_cpol=1, spi_cpha=0)
            //     2'b10: begin
            //         if (spi_clk == 1'b0) spi_rise = running; // 上升沿（数据采样）
            //         if (spi_clk == 1'b1) spi_fall = running; // 下降沿（数据切换）
            //     end
            //     // Mode 3 (spi_cpol=1, spi_cpha=1)
            //     2'b11: begin
            //         if (spi_clk == 1'b1) spi_rise = running; // 下降沿（数据切换）
            //         if (spi_clk == 1'b0) spi_fall = running; // 上升沿（数据采样）
            //     end
            // endcase
            if (spi_clk == 1'b0)
                spi_rise = running;
            else
                spi_fall = running;

	end else begin
            counter_next = counter + 1;
            spi_clk_next = spi_clk;
        end
    end

    always @(posedge clk or negedge rstn) begin
        if (rstn == 1'b0) begin
            counter_trgt <= 'h0;
            counter      <= 'h0;
            spi_clk      <= 1'b0;
            running      <= 1'b0;
	end else begin
            counter_trgt <= counter_trgt_next;

            if (!((spi_clk == 1'b0) && ~en)) begin
                running <= 1'b1;
                spi_clk <= spi_clk_next;
                counter <= counter_next;
	    end else
                running <= 1'b0;
        end
    end
    // always @(posedge clk or negedge rstn) begin
    //     if (!rstn) begin
    //         counter_trgt <= 0;
    //         counter      <= 0;
    //         spi_clk      <= idle_level;  // 根据 CPOL 初始化
    //         running      <= 0;
    //     end else begin
    //         counter_trgt <= counter_trgt_next;

    //         if (en) begin
    //             running <= 1'b1;
    //             spi_clk <= spi_clk_next;
    //             counter <= counter_next;
    //         end else begin
    //             running <= 1'b0;
    //             spi_clk <= idle_level;   // 失能时返回空闲电平
    //             counter <= 0;
    //         end
    //     end
    // end

endmodule
